package com.ims.core.doc.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

import com.baiwang.open.entity.response.*;
import com.baiwang.open.entity.response.node.*;
import com.ims.common.annotation.Log;
import com.ims.common.annotation.RequestParamsSplit;
import com.ims.common.core.domain.AjaxResult;
import com.ims.common.core.domain.entity.SysUser;
import com.ims.common.core.redis.RedisCache;
import com.ims.common.enums.BusinessType;
import com.ims.common.exception.ServiceException;
import com.ims.common.exception.base.BaseException;
import com.ims.common.utils.DateUtils;
import com.ims.common.utils.DictUtils;
import com.ims.common.utils.SecurityUtils;
import com.ims.common.utils.uuid.IdUtils;
import com.ims.core.doc.domain.*;
import com.ims.core.doc.mapper.TSalInvoiceMapper;
import com.ims.core.doc.mapper.TScSettlebillMapper;
import com.ims.core.doc.service.*;
import com.ims.core.doc.vo.bwapi.*;
import com.ims.core.enums.*;
import com.ims.core.saleconfig.domain.TSalBuyer;
import com.ims.core.saleconfig.domain.TSalProduct;
import com.ims.core.saleconfig.service.ITSalBuyerService;
import com.ims.core.saleconfig.service.ITSalProductService;
import com.ims.core.vo.TSalInvoiceResponse;
import com.ims.manager.ImsAsyncManager;
import com.ims.manager.factory.ImsAsyncFactory;
import com.ims.util.BaiwangUtils;
import org.apache.commons.math3.special.BesselJ;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import com.ims.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * 销项发票Service业务层处理
 *
 * @author IMS
 * @date 2024-05-07
 */
@Service
public class TSalInvoiceServiceImpl implements ITSalInvoiceService
{
    private static final Logger log = LoggerFactory.getLogger(TSalInvoiceServiceImpl.class);

    @Autowired
    private TSalInvoiceMapper tSalInvoiceMapper;

    @Autowired
    private TScSettlebillMapper tScSettlebillMapper;

    @Autowired
    private ITScSettlebillService tScSettlebillService;

    @Autowired
    private ITScSettleSalInvoiceService tScSettleSalInvoiceService;

    @Autowired
    private ITSalProductService tSalProductService;

    @Autowired
    private ITSalInvoiceIssueService tSalInvoiceIssueService;

    @Autowired
    private ITSalBuyerService tSalBuyerService;

    @Autowired
    private ITSalInvoiceRedConfirmService tSalInvoiceRedConfirmService;

    @Autowired
    private RedisCache redisCache;

    /**
     * 查询销项发票
     *
     * @param id 销项发票主键
     * @return 销项发票
     */
    @Override
    public TSalInvoice selectTSalInvoiceById(Long id)
    {
        TSalInvoice tSalInvoice = tSalInvoiceMapper.selectTSalInvoiceById(id);
        return tSalInvoice;
    }

    @Override
    public TSalInvoice selectTSalInvoiceByInvoiceNo(String invoiceNo) {
        return tSalInvoiceMapper.selectTSalInvoiceByInvoiceNo(invoiceNo);
    }

    @Override
    public TSalInvoiceResponse selectTSalInvoiceFullInfoById(Long id) {
        TSalInvoiceResponse tSalInvoiceResponse = new TSalInvoiceResponse();
        TSalInvoice tSalInvoice = tSalInvoiceMapper.selectTSalInvoiceById(id);
        BeanUtils.copyProperties(tSalInvoice, tSalInvoiceResponse);
        // 根据发票单号，查询发票
        tSalInvoiceResponse.settSalInvoiceIssue(tSalInvoiceIssueService.selectTSalInvoiceIssueByInvoiceId(tSalInvoice.getInvoiceId()));
        return tSalInvoiceResponse;
    }

    /**
     * 查询销项发票
     *
     * @param id 销项发票主键
     * @return 销项发票
     */
    @Override
    public TSalInvoice selectPreTSalInvoiceById(Long id, String searchType)
    {
        Map params = new HashMap<>();
        params.put("id", id);
        params.put("searchType", searchType);
        return tSalInvoiceMapper.selectPreTSalInvoiceById(params);
    }

    /**
     * 查询销项发票
     *
     * @param id 销项发票主键
     * @return 销项发票
     */
    @Override
    public TSalInvoice selectNextTSalInvoiceById(Long id, String searchType)
    {
        Map params = new HashMap<>();
        params.put("id", id);
        params.put("searchType", searchType);
        return tSalInvoiceMapper.selectNextTSalInvoiceById(params);
    }

    /**
     * 查询销项发票列表
     *
     * @param tSalInvoice 销项发票
     * @return 销项发票
     */
    @Override
    @RequestParamsSplit
    public List<TSalInvoice> selectTSalInvoiceList(TSalInvoice tSalInvoice)
    {
        return tSalInvoiceMapper.selectTSalInvoiceList(tSalInvoice);
    }

    /**
     * 新增销项发票
     *
     * @param tSalInvoice 销项发票
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertTSalInvoice(TSalInvoice tSalInvoice)
    {
        tSalInvoice.setCreateTime(DateUtils.getNowDate());
        int rows = tSalInvoiceMapper.insertTSalInvoice(tSalInvoice);
        if(rows > 0){
            insertTSalInvoiceEntry(tSalInvoice);
        }
        return rows;
    }

    /**
     * 修改销项发票
     *
     * @param tSalInvoice 销项发票
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateTSalInvoice(TSalInvoice tSalInvoice)
    {
        //提交人
        SysUser user = SecurityUtils.getLoginUser().getUser();
        tSalInvoiceMapper.deleteTSalInvoiceEntryByInvoiceId(tSalInvoice.getInvoiceId());
        insertTSalInvoiceEntry(tSalInvoice);
        tSalInvoice.setInvoiceTypeName(DictUtils.getDictLabel("invoice_type", tSalInvoice.getInvoiceType()));
        tSalInvoice.setUpdateBy(user.getUserName());
        tSalInvoice.setUpdateTime(DateUtils.getNowDate());
        return tSalInvoiceMapper.updateTSalInvoice(tSalInvoice);
    }

    /**
     * 批量删除销项发票
     *
     * @param ids 需要删除的销项发票主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteTSalInvoiceByIds(Long[] ids)
    {
        //
        for(Long id : ids){
            TSalInvoice tSalInvoice = selectTSalInvoiceById(id);
            if(tSalInvoice.getProcessStatus().equals(ProcessStatus.INVOICING.getCode())
            || tSalInvoice.getProcessStatus().equals(ProcessStatus.INVOICED.getCode())
            ){
                throw new ServiceException("发票号" + tSalInvoice.getApplyNo() + "为 [" + DictUtils.getDictLabel("process_status", tSalInvoice.getProcessStatus()) + "],无法删除！");
            } else {
                // tSalInvoiceMapper.deleteTSalInvoiceEntryByInvoiceId(tSalInvoice.getInvoiceId());
                deleteTSalInvoiceById(id);
            }
        }
        return 1;
    }


    @Override
    public void issueTSalInvoiceByIds(Long[] ids) {
        //提交人
        SysUser user = SecurityUtils.getLoginUser().getUser();
        for(long id : ids){
            try {
                issueByTSalInvoice(tSalInvoiceMapper.selectTSalInvoiceById(id));
            } catch (BaseException be) {
                // 找到对应的结算单，更新开票失败
                TSalInvoice tSalInvoice = tSalInvoiceMapper.selectTSalInvoiceById(id);
                if(!StringUtils.isEmpty(tSalInvoice.getSettleId())){
                    TScSettlebill scSettlebill = tScSettlebillService.selectTScSettlebillBySettleId(tSalInvoice.getSettleId());
                    scSettlebill.setErrorMsg(be.getMessage());
                    tScSettlebillService.updateTScSettlebillOnly(scSettlebill);
                }
            } catch (ServiceException se) {
                // 找到对应的结算单，更新开票失败
                TSalInvoice tSalInvoice = tSalInvoiceMapper.selectTSalInvoiceById(id);
                if(!StringUtils.isEmpty(tSalInvoice.getSettleId())){
                    TScSettlebill scSettlebill = tScSettlebillService.selectTScSettlebillBySettleId(tSalInvoice.getSettleId());
                    scSettlebill.setErrorMsg(se.getMessage());
                    tScSettlebillService.updateTScSettlebillOnly(scSettlebill);
                }
            }

        }
    }

    @Override
    public TSalInvoiceRedConfirm redTSalInvoiceByIdAndReason(Long id, String reason) {
        TSalInvoice tSalInvoice = tSalInvoiceMapper.selectTSalInvoiceById(id);
        // 校验处理状态
        if(!tSalInvoice.getProcessStatus().equals(ProcessStatus.INVOICED.getCode())){
            throw new ServiceException("提示 选择的数据必须为已开票状态，请检查！");
        }
        // 获取发票
        TSalInvoiceIssue originalSalInvoiceIssue = tSalInvoiceIssueService.selectTSalInvoiceIssueByInvoiceId(tSalInvoice.getInvoiceId());

        // 百望红冲接口对象
        InvoiceForRed invoiceForRed = new InvoiceForRed();
        BeanUtils.copyProperties(tSalInvoice, invoiceForRed);
        invoiceForRed.setApplyNo(originalSalInvoiceIssue.getSerialNo());
        invoiceForRed.setInvoiceTotalTax(originalSalInvoiceIssue.getInvoiceTotalTax());
        // originInvoiceTotalPrice
        invoiceForRed.setInvoiceTotalPrice(originalSalInvoiceIssue.getInvoiceTotalPrice());
        // invoiceTotalPrice
        invoiceForRed.setRedTotalPrice(originalSalInvoiceIssue.getInvoiceTotalPrice());
        invoiceForRed.setRedTotalTax(originalSalInvoiceIssue.getInvoiceTotalTax());
        invoiceForRed.setBuyerTel(tSalInvoice.getBuyerTel());
        // 红字发票冲红原因代码 01:开票有误 02:销货退回 03:服务中止 04:销售折让。二手车销售统一发票仅可使用01、02
        invoiceForRed.setRedReason(reason);
        try {
            invoiceForRed.setInvoiceDate(originalSalInvoiceIssue.getInvoiceDate() );
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("蓝字发票开票日期不正确");
        }
        List<InvoiceEntryForRed> invoiceEntryForRedList = new ArrayList<>();
        for(TSalInvoiceIssueEntry tSalInvoiceIssueEntry : originalSalInvoiceIssue.getTSalInvoiceIssueEntryList()){
            InvoiceEntryForRed invoiceEntryForRed = new InvoiceEntryForRed();
            // originalInvoiceDetailNo	Integer	8	是	蓝字发票明细序号
            invoiceEntryForRed.setGoodsLineNo(tSalInvoiceIssueEntry.getGoodsLineNo());
            // goodsCode	String	19	是	税收分类编码(商品和服务税收分类合并编码)
            invoiceEntryForRed.setProductCode(tSalInvoiceIssueEntry.getGoodsCode());
            // goodsName	String	300	否	商品全称（ 简称自定义名称）projectName	String	600	是	项目名称(自定义商品名称)
            invoiceEntryForRed.setProductName(tSalInvoiceIssueEntry.getGoodsName());
            // goodsSpecification	String	150	否	规格型号，也可代表车架号/车辆识别号
            invoiceEntryForRed.setSpecificatCode(tSalInvoiceIssueEntry.getGoodsSpecification());
            // goodsUnit	String	300	否	单位
            invoiceEntryForRed.setUnit(tSalInvoiceIssueEntry.getGoodsUnit());
            // goodsQuantity	String	25	否	数量
            invoiceEntryForRed.setQty(tSalInvoiceIssueEntry.getGoodsQuantity());
            // goodsTaxRate	BigDecimal	16,6	是	税率
            invoiceEntryForRed.setTaxRate(tSalInvoiceIssueEntry.getGoodsTaxRate());
            // goodsTotalTax	BigDecimal	18,2	是	税额
            invoiceEntryForRed.setTax(tSalInvoiceIssueEntry.getGoodsTotalTax());
            // goodsPriceTax	BigDecimal	18,2	否	含税单价，当含税标志为1-含税时，如需要，传此值
            invoiceEntryForRed.setPrice(tSalInvoiceIssueEntry.getGoodsPrice());
            // goodsTotalPriceTax	BigDecimal	18,2	条件必填	含税金额，当含税标志为1-含税时，传此值
            invoiceEntryForRed.setAmount(tSalInvoiceIssueEntry.getGoodsTotalPrice());
            invoiceEntryForRedList.add(invoiceEntryForRed);
            if(StringUtils.isEmpty(invoiceForRed.getPriceTaxMark())){
                invoiceForRed.setPriceTaxMark(tSalInvoiceIssueEntry.getPriceTaxMark());
            }
        }
        invoiceForRed.setInvoiceEntryForRedList(invoiceEntryForRedList);
        // 百望开具接口，红冲对象明细
        OutputRedinvoiceAddResponse response = BaiwangUtils.redInvoiceAdd(invoiceForRed);
        // 保存红冲接口的返回
        TSalInvoiceRedConfirm tSalInvoiceRedConfirm = convertToTSalInvoiceRedConfirm(tSalInvoice, response);
        tSalInvoiceRedConfirmService.insertTSalInvoiceRedConfirm(tSalInvoiceRedConfirm);
        if(!tSalInvoiceRedConfirm.getReturnCode().equals("0")){
            throw new ServiceException("税务接口异常：" + response.getErrorResponse().getMessage());
        }
        // Y：确认即开
        // N或空：非确认即开; 连接器开票用
        if(tSalInvoiceRedConfirm.getConfirmBillingMark().equals("Y")){
            // 异步调用查询接口( 即 queryAndSaveInvoiceByInvoiceNo 方法)
            ImsAsyncManager.me().execute(ImsAsyncFactory.syncInvoiceFromBaiwangDelay(tSalInvoice.getSellerNumber(), tSalInvoice.getApplyNo(), tSalInvoiceRedConfirm.getRedinvoiceNo()));
        }
        return tSalInvoiceRedConfirm;
    }

    /**
     * 删除销项发票信息
     *
     * @param id 销项发票主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteTSalInvoiceById(Long id)
    {
        //提交人
        SysUser user = SecurityUtils.getLoginUser().getUser();
        /*
            删除销项发票
            1. 判断发票状态，若非待开票状态，则无法删除，提示 选择的数据中包含开票中或锁定单据的数据，请检查！
            2. 根据当前有效的 发票-结算单 映射关系（或发票中的settleId） 查询对应的结算单
            3. 将2中结算单对应的此发票的可开票明细（根据开票号码查询）重新开放（恢复可用，然后按物料合并查出该结算单剩余所有可开票明细，先作废所有可开票明细后重新插回表）
                ；若没有可用开票明细，则不用处理
            4. 重新计算该结算单的待开票金额（此次删除发票对应的金额，需和3中明细的总额一致）和处理状态（改为待处理），修改拆分状态和解除合并状态
            5. 标记该发票为删除，标记该 发票-结算单 映射关系 为废除
         */
        // 1
        TSalInvoice tSalInvoice = tSalInvoiceMapper.selectTSalInvoiceById(id);
        if(!tSalInvoice.getProcessStatus().equals(ProcessStatus.PENDING_INVOICING.getCode())){
            throw new ServiceException("提示 选择的数据中包含开票中或锁定单据的数据，请检查！");
        }
        TScSettleSalInvoice tScSettleSalInvoiceCondition = new TScSettleSalInvoice();
        tScSettleSalInvoiceCondition.setInvoiceId(tSalInvoice.getInvoiceId());
        tScSettleSalInvoiceCondition.setIsDel(0);
        List<TScSettleSalInvoice> tScSettleSalInvoiceList = tScSettleSalInvoiceService.selectTScSettleSalInvoiceList(tScSettleSalInvoiceCondition);
        if(CollectionUtils.isEmpty(tScSettleSalInvoiceList)){
            throw new ServiceException("提示 无法找到原结算单，请检查！");
        }
        // 2 循环结算单结果集
        for(TScSettleSalInvoice tScSettleSalInvoice : tScSettleSalInvoiceList){
            // 查询这个结算单
            TScSettlebill tScSettlebill = tScSettlebillService.selectTScSettlebillBySettleId(tScSettleSalInvoice.getSettleId());

            // 可开票明细的金额
            BigDecimal pendingFee = BigDecimal.ZERO;

            // 查询这个结算单 和 对应此发票的开票明细(状态应为已删除)
            Map<String, String> params = new HashMap<>();
            params.put("settleId", tScSettleSalInvoice.getSettleId());
            params.put("version", tSalInvoice.getApplyNo());
            List<TScSettlebillEntryForinvoice> tScSettlebillEntryForinvoiceList = tScSettlebillMapper.selectTScSettlebillEntryForinvoiceListBySettleIdAndApplyNo(params);
            if(CollectionUtils.isEmpty(tScSettlebillEntryForinvoiceList)){
                // throw new ServiceException("提示 无法找到原结算单开票明细，请检查！");
                log.info("原结算单{} 无可开票明细，原结算单上一次操作为整单开票，可开票的金额恢复为原结算单金额");
                //
                pendingFee = tScSettlebill.getFee();
            } else {
                // 恢复 tScSettlebillEntryForinvoiceList 并按物料合并查出该结算单剩余所有可开票明细
                // 目前该结算单可用的开票明细
                List<TScSettlebillEntryForinvoice> tScSettlebillEntryForinvoiceLastList = tScSettlebillMapper.selectLastTScSettlebillEntryForinvoiceList(tScSettleSalInvoice.getSettleId());
                // 合并 发票的开票明细 和 目前该结算单可用的开票明细
                tScSettlebillEntryForinvoiceList.addAll(tScSettlebillEntryForinvoiceLastList);
                // 按物料合并
                List<TScSettlebillEntryForinvoice> newTScSettlebillEntryForinvoiceList = tScSettlebillMapper.getNewTScSettlebillEntryForinvoiceList(tScSettlebillEntryForinvoiceList);
                // 作废该结算单可用的开票明细，版本号标记为
                params.put("version", tSalInvoice.getApplyNo()+"undo");
                tScSettlebillMapper.deleteTScSettlebillEntryForinvoiceBySettleId(params);
                // 插入 按物料合并 后的可开票明细
                tScSettlebillMapper.batchTScSettlebillEntryForinvoice(newTScSettlebillEntryForinvoiceList);

                // 4. 重新计算该结算单的待开票金额（此次删除发票对应的金额，需和3中明细的总额一致）和处理状态（改为待处理）
                for(TScSettlebillEntryForinvoice tScSettlebillEntryForinvoice : newTScSettlebillEntryForinvoiceList){
                    pendingFee = tScSettlebillEntryForinvoice.getAmount().add(pendingFee);
                }
            }

            // 更新待开票金额
            tScSettlebill.setPendingFee(pendingFee);
            // 更新处理状态为待处理
            tScSettlebill.setSettlebillStatus(SettlebillStatus.UNCOMPLETED.getCode());
            tScSettlebill.setSettlebillStatusName(SettlebillStatus.UNCOMPLETED.getName());
            // 待开票金额若小于结算单总金额，则表示该结算单是被拆分过的
            if(pendingFee.compareTo(tScSettlebill.getFee()) < 0){
                tScSettlebill.setSplitStatus(SplitStatus.SPLIT.getCode());
                tScSettlebill.setSplitStatusName(SplitStatus.SPLIT.getName());
            } else {
                tScSettlebill.setSplitStatus(SplitStatus.NOT_SPLIT.getCode());
                tScSettlebill.setSplitStatusName(SplitStatus.NOT_SPLIT.getName());
            }
            // 解除合并状态
            tScSettlebill.setMergeIdent(MergeIdent.NOT_MERGED.getCode());
            tScSettlebill.setMergeIdentName(MergeIdent.NOT_MERGED.getName());
            // 更新结算单
            tScSettlebill.setUpdateTime(new Date());
            tScSettlebill.setUpdateBy(user.getUserName());
            tScSettlebillMapper.updateTScSettlebill(tScSettlebill);
            // 标记该 发票-结算单 映射关系 为废除
            tScSettleSalInvoice.setIsDel(1);
            tScSettleSalInvoice.setUpdateTime(new Date());
            tScSettleSalInvoice.setUpdateBy(user.getUserName());
            tScSettleSalInvoiceService.updateTScSettleSalInvoice(tScSettleSalInvoice);
        }
        // 5. 标记该发票为删除，标记该 发票-结算单 映射关系 为废除
        return tSalInvoiceMapper.deleteTSalInvoiceById(id);
    }

    /**
     * 新增销项明细项信息
     *
     * @param tSalInvoice 销项发票对象
     */
    public void insertTSalInvoiceEntry(TSalInvoice tSalInvoice)
    {
        List<TSalInvoiceEntry> tSalInvoiceEntryList = tSalInvoice.getTSalInvoiceEntryList();
        if (StringUtils.isNotNull(tSalInvoiceEntryList))
        {
            List<TSalInvoiceEntry> list = new ArrayList<TSalInvoiceEntry>();
            for (TSalInvoiceEntry tSalInvoiceEntry : tSalInvoiceEntryList)
            {
                tSalInvoiceEntry.setEntryId(IdUtils.simpleUUID());
                tSalInvoiceEntry.setInvoiceId(tSalInvoice.getInvoiceId());
                list.add(tSalInvoiceEntry);
            }
            if (list.size() > 0)
            {
                // 分段插入，数据量太大引起mysql报错
                int steps = list.size() / 10;
                steps ++;
                int start = 0;
                int end = 0;
                for(int step = 0 ; step < steps; step ++){
                    start = step * 10;
                    end = (step + 1) * 10;
                    if(step == ( steps -1 )){
                        end = list.size();
                    }
                    List<TSalInvoiceEntry> subList = list.subList(start, end);
                    if(!CollectionUtils.isEmpty(subList)){
                        tSalInvoiceMapper.batchTSalInvoiceEntry(subList);
                    }
                }

            }
        }
    }

    @Override
    public TSalInvoice createTSalInvoiceByTScSettlebill(TScSettlebillRequest tScSettlebillRequest) {
        // 生成
        TSalInvoice tSalInvoice = generateInvoiceBySettlebill(tScSettlebillRequest);
        // 生成明细
        List<TSalInvoiceEntry> tSalInvoiceEntryList = generateInvoiceEntryListBySettlebill(tScSettlebillRequest);
        tSalInvoice.setTSalInvoiceEntryList(tSalInvoiceEntryList);

        return tSalInvoice;
    }

    @Override
    public TSalInvoice createTSalInvoiceByMergeTScSettlebill(TScSettlebillRequest tScSettlebillRequest) {
        // 生成
        TSalInvoice tSalInvoice = generateInvoiceByMergeSettlebill(tScSettlebillRequest);
        // 生成明细
        List<TSalInvoiceEntry> tSalInvoiceEntryList = generateInvoiceEntryListBySettlebill(tScSettlebillRequest);
        //
        for(TSalInvoiceEntry tSalInvoiceEntry : tSalInvoiceEntryList){
            tSalInvoiceEntry.setSettleId("合并");
            tSalInvoiceEntry.setOrderNo("合并");
            tSalInvoiceEntry.setSourceOrderNo("合并");
        }
        tSalInvoice.setTSalInvoiceEntryList(tSalInvoiceEntryList);
        return tSalInvoice;
    }

    /**
     *
     * @param taxNo  销方机构税号
     * @param applyNo  发票单号
     * @param invoiceNo  发票号码
     */
    @Override
    public void queryAndSaveInvoiceByInvoiceNo(String taxNo, String applyNo, String invoiceNo) {
        OutputEinvoiceQueryResponse response = BaiwangUtils.queryInvoiceByInvoiceNo(taxNo, invoiceNo);
        if(!response.getSuccess()){
            log.error("发票 {}查询失败 {}, {}", invoiceNo, response.getErrorResponse().getCode(), response.getErrorResponse().getMessage());
        } else {
            if(CollectionUtils.isEmpty(response.getResponse())){
                log.error("发票 {} 无返回结果", invoiceNo);
            } else {
                OutputEinvoiceQuery outputInvoiceQuery = response.getResponse().get(0);
                // 如果本地不存在，则转为本地发票对象(tSalInvoice 和 tSalInvoiceIssue)
                TSalInvoice tSalInvoice = selectTSalInvoiceByInvoiceNo(invoiceNo);
                if(tSalInvoice == null){
                    tSalInvoice = new TSalInvoice();
                    tSalInvoice.setInvoiceId(IdUtils.simpleUUID());
                    tSalInvoice.setInvoiceType(outputInvoiceQuery.getInvoiceTypeCode());
                    tSalInvoice.setInvoiceTypeName(DictUtils.getDictLabel("invoice_type", outputInvoiceQuery.getInvoiceTypeCode()));
                    // 开票类型 0:正数发票（蓝票） 1：负数发票（红票）默认0
                    if(tSalInvoice.getInvoiceType().equals("0")){
                        tSalInvoice.setInvoiceFlag(1);
                        tSalInvoice.setNatureType(1);
                        tSalInvoice.setApplyNo(outputInvoiceQuery.getSerialNo());
                    } else {
                        tSalInvoice.setInvoiceFlag(0);
                        tSalInvoice.setNatureType(0);
                        tSalInvoice.setApplyNo(IdUtils.getServiceNo("HC"));
                        // 需要同步原蓝票信息
                        // 异步调用查询接口( 即 queryAndSaveInvoiceByInvoiceNo 方法)
                        TSalInvoice orgTSalInvoice = selectTSalInvoiceByInvoiceNo(outputInvoiceQuery.getOriginalInvoiceNo());
                        tSalInvoice.setOrderNo(orgTSalInvoice.getOrderNo());
                        tSalInvoice.setSettleId(orgTSalInvoice.getSettleId());
                        tSalInvoice.setCollectMail(orgTSalInvoice.getCollectMail());
                        tSalInvoice.setCollectMobile(orgTSalInvoice.getCollectMobile());
                        ImsAsyncManager.me().execute(ImsAsyncFactory.syncInvoiceFromBaiwang(orgTSalInvoice.getSellerNumber(), orgTSalInvoice.getApplyNo(), orgTSalInvoice.getInvoiceNo()));
                    }
                    tSalInvoice.setInvoiceNo(outputInvoiceQuery.getInvoiceNo());
                    // tSalInvoice.setInvoiceCode(outputInvoiceQuery.getInvoiceCode());
                    tSalInvoice.setInvoiceDate(outputInvoiceQuery.getInvoiceDate());
                    tSalInvoice.setFee(outputInvoiceQuery.getInvoiceTotalPriceTax());
                    tSalInvoice.setTax(outputInvoiceQuery.getInvoiceTotalTax());
                    tSalInvoice.setFeeWithoutTax(outputInvoiceQuery.getInvoiceTotalPrice());

                    // 销方
                    tSalInvoice.setSellerName(outputInvoiceQuery.getSellerName());
                    tSalInvoice.setSellerNumber(outputInvoiceQuery.getSellerTaxNo());
                    tSalInvoice.setSellerAddress(outputInvoiceQuery.getSellerAddress());
                    tSalInvoice.setSellerTel(outputInvoiceQuery.getSellerTelphone());
                    tSalInvoice.setSellerBank(outputInvoiceQuery.getSellerBankName());
                    tSalInvoice.setSellerAccount(outputInvoiceQuery.getSellerBankNumber());
                    // 购方
                    tSalInvoice.setBuyerName(outputInvoiceQuery.getBuyerName());
                    tSalInvoice.setBuyerNumber(outputInvoiceQuery.getBuyerTaxNo());
                    tSalInvoice.setBuyerAddress(outputInvoiceQuery.getBuyerAddress());
                    tSalInvoice.setBuyerTel(outputInvoiceQuery.getBuyerTelphone());
                    tSalInvoice.setBuyerBank(outputInvoiceQuery.getBuyerBankName());
                    tSalInvoice.setBuyerAccount(outputInvoiceQuery.getBuyerBankNumber());

                    // tSalInvoice.setCollectMobile(outputInvoiceQuery.getbuyerEmail);
                    // tSalInvoice.setCollectMobile(outputInvoiceQuery.getBuyerp);

                    tSalInvoice.setProcessStatus(ProcessStatus.INVOICED.getCode());
                    tSalInvoice.setProcessStatusName(ProcessStatus.INVOICED.getName());
                    // 00 开具成功 03 发票作废
                    if(outputInvoiceQuery.getInvoiceStatus().equals("00")){
                        tSalInvoice.setInvoiceStatus(InvoiceStatus.NORMAL.getCode());
                        tSalInvoice.setInvoiceStatusName(InvoiceStatus.NORMAL.getName());
                        // 0 未红冲 1 全额红冲 2 部分红冲'
                        if(outputInvoiceQuery.getRedDashedStatus().equals("1")){
                            tSalInvoice.setInvoiceStatus(InvoiceStatus.NORMAL.getCode());
                            tSalInvoice.setInvoiceStatusName(InvoiceStatus.NORMAL.getName());
                        } else if(outputInvoiceQuery.getRedDashedStatus().equals("1")){
                            tSalInvoice.setInvoiceStatus(InvoiceStatus.RED_FLUSH.getCode());
                            tSalInvoice.setInvoiceStatusName(InvoiceStatus.RED_FLUSH.getName());
                        } else if(outputInvoiceQuery.getRedDashedStatus().equals("2")){
                            tSalInvoice.setInvoiceStatus(InvoiceStatus.PART_RED_FLUSH.getCode());
                            tSalInvoice.setInvoiceStatusName(InvoiceStatus.PART_RED_FLUSH.getName());
                        }
                    } else {
                        tSalInvoice.setInvoiceStatus(InvoiceStatus.INVALID.getCode());
                        tSalInvoice.setInvoiceStatusName(InvoiceStatus.INVALID.getName());

                    }
                    // tSalInvoice.setCheckCode(outputInvoiceQuery.getche);
                    tSalInvoice.setInvoiceRemark(outputInvoiceQuery.getRemarks());
//                tSalInvoice.setNullifier(outputInvoiceQuery.getInvoiceInvalidOperator());
//                if(!StringUtils.isEmpty(outputInvoiceQuery.getInvoiceInvalidDate())){
//                    tSalInvoice.setInvalidTime(DateUtils.dateTime("yyyy-MM-dd",outputInvoiceQuery.getInvoiceInvalidDate()) );
//                }
                    tSalInvoice.setOrgInvoiceNo(outputInvoiceQuery.getOriginalInvoiceNo());
                    tSalInvoice.setInvoiceName(outputInvoiceQuery.getDrawer());
                    // tSalInvoice.setCollectName(outputInvoiceQuery.getCollectionBankName() + outputInvoiceQuery.getCollectionBankAccount());
                    // tSalInvoice.setReviewName(outputInvoiceQuery.getChecker());
                    tSalInvoice.setCreateBy("查询接口生成");
                    tSalInvoice.setCreateTime(new Date());

                    // 发票明细
                    List<TSalInvoiceEntry> tSalInvoiceEntryList = new ArrayList<>();
                    List<TSalInvoiceIssueEntry> tSalInvoiceIssueEntryList = new ArrayList<>();

                    List<OutputEinvoiceQueryInvoiceQueryInvoiceDetail> invoiceDetailsList = outputInvoiceQuery.getElectricInvoiceDetails();
                    for(OutputEinvoiceQueryInvoiceQueryInvoiceDetail queryInvoiceDetail : invoiceDetailsList){
                        TSalInvoiceEntry tSalInvoiceEntry = new TSalInvoiceEntry();
                        TSalInvoiceIssueEntry tSalInvoiceIssueEntry = new TSalInvoiceIssueEntry();
                        tSalInvoiceEntry.setSettleId(tSalInvoice.getSettleId());
                        tSalInvoiceEntry.setEntryId(IdUtils.simpleUUID());
                        tSalInvoiceIssueEntry.setEntryId(IdUtils.simpleUUID());

                        tSalInvoiceEntry.setProductCode(queryInvoiceDetail.getGoodsCode());
                        tSalInvoiceEntry.setProductName(queryInvoiceDetail.getGoodsName());

                        tSalInvoiceIssueEntry.setGoodsCode(queryInvoiceDetail.getGoodsCode());
                        tSalInvoiceIssueEntry.setGoodsName(queryInvoiceDetail.getGoodsName());

                        tSalInvoiceEntry.setSpecificatCode(queryInvoiceDetail.getGoodsSpecification());
                        tSalInvoiceIssueEntry.setGoodsSpecification(queryInvoiceDetail.getGoodsSpecification());

                        tSalInvoiceEntry.setUnit(queryInvoiceDetail.getGoodsUnit());
                        tSalInvoiceIssueEntry.setGoodsUnit(queryInvoiceDetail.getGoodsUnit());

                        tSalInvoiceEntry.setQty(queryInvoiceDetail.getGoodsQuantity());
                        tSalInvoiceIssueEntry.setGoodsQuantity(queryInvoiceDetail.getGoodsQuantity());

                        // 单价(不含税)
                        // tSalInvoiceEntry.setWithoutPrice(queryInvoiceDetail.getExcludTaxgoodsPrice());

                        // 金额(不含税)
                        // tSalInvoiceEntry.setWithoutAmount(queryInvoiceDetail.getExcludTaxgoodsTotalPrice());

                        // 税率
                        tSalInvoiceEntry.setTaxRate(queryInvoiceDetail.getGoodsTaxRate().multiply(new BigDecimal(100)));
                        tSalInvoiceIssueEntry.setGoodsTaxRate(queryInvoiceDetail.getGoodsTaxRate());

                        // 税额
                        tSalInvoiceEntry.setTax(queryInvoiceDetail.getGoodsTotalTax());
                        tSalInvoiceIssueEntry.setGoodsTotalTax(queryInvoiceDetail.getGoodsTotalTax());

                        // 单价(含税)
                        tSalInvoiceEntry.setPrice(queryInvoiceDetail.getGoodsTotalPriceTax().divide(queryInvoiceDetail.getGoodsQuantity()).setScale(2, RoundingMode.HALF_UP));
                        tSalInvoiceIssueEntry.setGoodsPrice(queryInvoiceDetail.getGoodsPrice());

                        // 金额(含税)
                        tSalInvoiceEntry.setAmount(queryInvoiceDetail.getGoodsTotalPriceTax());
                        tSalInvoiceIssueEntry.setGoodsTotalPrice(queryInvoiceDetail.getGoodsTotalPrice());

                        tSalInvoiceIssueEntry.setGoodsLineNo(Integer.parseInt(queryInvoiceDetail.getGoodsLineNo()));
                        tSalInvoiceIssueEntry.setInvoiceLineNature(queryInvoiceDetail.getInvoiceLineNature());
                        // tSalInvoiceIssueEntry.setPriceTaxMark(queryInvoiceDetail.getPriceTaxMark());
                        tSalInvoiceIssueEntry.setVatSpecialManagement(queryInvoiceDetail.getVatSpecialManagement());
                        // tSalInvoiceIssueEntry.setFreeTaxMark(queryInvoiceDetail.getFreeTaxMark());
                        // tSalInvoiceIssueEntry.setPreferentialMark(queryInvoiceDetail.getPreferentialMark());
                        tSalInvoiceEntry.setCreateBy("查询接口生成");
                        tSalInvoiceEntry.setCreateTime(new Date());

                        tSalInvoiceEntryList.add(tSalInvoiceEntry);

                        tSalInvoiceIssueEntry.setCreateBy("查询接口生成");
                        tSalInvoiceIssueEntry.setCreateTime(new Date());
                        tSalInvoiceIssueEntryList.add(tSalInvoiceIssueEntry);
                    }

                    TSalInvoiceIssue tSalInvoiceIssue = new TSalInvoiceIssue();
                    tSalInvoiceIssue.setResultId(IdUtils.simpleUUID());
                    tSalInvoiceIssue.setRequestId(response.getRequestId());
                    tSalInvoiceIssue.setInvoiceId(tSalInvoice.getInvoiceId());
                    // 开票流水号
                    tSalInvoiceIssue.setSerialNo(outputInvoiceQuery.getSerialNo());
                    // 发票代码
                    // tSalInvoiceIssue.setInvoiceCode(outputInvoiceQuery.getInvoiceCode());
                    // 发票号码
                    tSalInvoiceIssue.setInvoiceNo(invoiceNo);
                    // 合计金额，保留两位小数
                    tSalInvoiceIssue.setInvoiceTotalPrice(outputInvoiceQuery.getInvoiceTotalPrice());
                    // 合计税额，保留两位小数
                    tSalInvoiceIssue.setInvoiceTotalTax(outputInvoiceQuery.getInvoiceTotalTax());
                    // 价税合计，保留两位小数
                    tSalInvoiceIssue.setInvoiceTotalPriceTax(outputInvoiceQuery.getInvoiceTotalPriceTax());
                    // 发票类型代码
                    tSalInvoiceIssue.setInvoiceTypeCode(outputInvoiceQuery.getInvoiceTypeCode());
                    // 开票日期
                    tSalInvoiceIssue.setInvoiceDate(outputInvoiceQuery.getInvoiceDate());
                    // 税控码
                    // tSalInvoiceIssue.setTaxControlCode(outputInvoiceQuery.getTaxControlCode());
                    // 备注
                    tSalInvoiceIssue.setRemark(outputInvoiceQuery.getRemarks());
                    // 校验码
                    // tSalInvoiceIssue.setInvoiceCheckCode(outputInvoiceQuery.getInvoiceCheckCode());
                    // 二维码
                    tSalInvoiceIssue.setInvoiceQrCode(outputInvoiceQuery.getInvoiceQrCode());
                    // 电子发票下载地址
                    tSalInvoiceIssue.seteInvoicePdfUrl(outputInvoiceQuery.getEInvoiceUrl());
                    tSalInvoiceIssue.setCreateBy("查询接口生成");
                    tSalInvoiceIssue.setCreateTime(new Date());

                    tSalInvoice.setTSalInvoiceEntryList(tSalInvoiceEntryList);
                    tSalInvoiceIssue.setTSalInvoiceIssueEntryList(tSalInvoiceIssueEntryList);

                    // 保存
                    insertTSalInvoice(tSalInvoice);
                    if(tSalInvoiceIssueService.insertTSalInvoiceIssue(tSalInvoiceIssue) == 1){
                    }
                }
                else {
                    // 更新蓝票信息（判断红冲状态，并更新）
                    // 0 未红冲 1 全额红冲 2 部分红冲'
                    if(outputInvoiceQuery.getRedDashedStatus().equals("0")){
                        tSalInvoice.setInvoiceStatus(InvoiceStatus.NORMAL.getCode());
                        tSalInvoice.setInvoiceStatusName(InvoiceStatus.NORMAL.getName());
                    } else if(outputInvoiceQuery.getRedDashedStatus().equals("1")){
                        tSalInvoice.setInvoiceStatus(InvoiceStatus.RED_FLUSH.getCode());
                        tSalInvoice.setInvoiceStatusName(InvoiceStatus.RED_FLUSH.getName());
                    } else if(outputInvoiceQuery.getRedDashedStatus().equals("2")){
                        tSalInvoice.setInvoiceStatus(InvoiceStatus.PART_RED_FLUSH.getCode());
                        tSalInvoice.setInvoiceStatusName(InvoiceStatus.PART_RED_FLUSH.getName());
                    }
                    tSalInvoice.setInvoiceType(outputInvoiceQuery.getInvoiceTypeCode());
                    tSalInvoice.setInvoiceTypeName(DictUtils.getDictLabel("invoice_type", tSalInvoice.getInvoiceType()));
                    if(!StringUtils.isEmpty(tSalInvoice.getInvoiceRemark())){
                        if(!StringUtils.isEmpty(outputInvoiceQuery.getRemarks())){
                            tSalInvoice.setInvoiceRemark(tSalInvoice.getInvoiceRemark()  + ";" +  outputInvoiceQuery.getRemarks());
                        }
                    } else {
                        if(!StringUtils.isEmpty(outputInvoiceQuery.getRemarks())){
                            tSalInvoice.setInvoiceRemark(outputInvoiceQuery.getRemarks());
                        }
                    }
                    tSalInvoice.setUpdateBy("发票同步");
                    tSalInvoice.setUpdateTime(DateUtils.getNowDate());
                    if(tSalInvoiceMapper.updateTSalInvoice(tSalInvoice) == 1){
                        //  TSalInvoiceIssue 更新
                        TSalInvoiceIssue tSalInvoiceIssue = tSalInvoiceIssueService.selectTSalInvoiceIssueByInvoiceId(tSalInvoice.getInvoiceId());
                        tSalInvoiceIssue.setInvoiceDate(outputInvoiceQuery.getInvoiceDate());
                        tSalInvoiceIssue.seteInvoicePdfUrl(outputInvoiceQuery.getEInvoiceUrl());
                        tSalInvoiceIssueService.updateTSalInvoiceIssueOnly(tSalInvoiceIssue);

                        // 异步调用版式生成接口
                        ImsAsyncManager.me().execute(ImsAsyncFactory.invoiceFormatCreateFromBaiwang(taxNo, tSalInvoice.getInvoiceNo()));
                    }
                }
                // 更新对应的结算单，回写状态改为【待同步】
                if(!StringUtils.isEmpty(tSalInvoice.getSettleId())){
                    TScSettlebill scSettlebill = tScSettlebillService.selectTScSettlebillBySettleId(tSalInvoice.getSettleId());
                    scSettlebill.setReturnErpStatus(ReturnErpStatus.TOBE.getCode());
                    scSettlebill.setReturnErpStatusName(ReturnErpStatus.TOBE.getName());
                    // 发票链接
                    scSettlebill.setReturnErpDescription(outputInvoiceQuery.getEInvoiceUrl());
                    tScSettlebillService.updateTScSettlebillOnly(scSettlebill);
                }
                // 异步调用版式生成接口
                ImsAsyncManager.me().execute(ImsAsyncFactory.invoiceFormatCreateFromBaiwang(taxNo, tSalInvoice.getInvoiceNo()));
            }
        }
    }

    /**
     * 根据发票号码请求版式生成
     * @param taxNo  销方机构税号
     * @param invoiceNo  发票号码
     */
    @Override
    public void formatCreateByInvoiceNo(String taxNo, String invoiceNo) {
        // 请求版式生成
        InvoiceForFormatCreate invoiceForFormatCreate = new InvoiceForFormatCreate();
        invoiceForFormatCreate.setTaxNo(taxNo);
        invoiceForFormatCreate.setEinvoiceNo(invoiceNo);
        invoiceForFormatCreate.setInvoiceIssueMode("1");
        OutputFormatCreateResponse response = BaiwangUtils.formatCreate(invoiceForFormatCreate);
        if(!response.getSuccess()){
            log.error("发票 {} 版式生成失败 {}, {}", invoiceNo, response.getErrorResponse().getCode(), response.getErrorResponse().getMessage());
        } else {
            // 存入t_sal_invoice_issue表
            OutputFormatCreateUrlMap formatCreateUrlMap = response.getResponse().getUrlMap();
            // 查询 tSalInvoiceIssue
            TSalInvoiceIssue tSalInvoiceIssue = tSalInvoiceIssueService.selectTSalInvoiceIssueByInvoiceNo(invoiceNo);
            log.info("发票 {} 发票版式获取成功", invoiceNo);
            log.info("当前的PDF地址：", tSalInvoiceIssue.geteInvoicePdfUrl());
            log.info("当前的OFD地址：", tSalInvoiceIssue.geteInvoiceOfdUrl());
            log.info("当前的XML地址：", tSalInvoiceIssue.geteInvoiceXmlUrl());

            if(!Objects.isNull(tSalInvoiceIssue)){
                tSalInvoiceIssue.seteInvoicePdfUrl(formatCreateUrlMap.getPdfUrl());
                tSalInvoiceIssue.seteInvoiceOfdUrl(formatCreateUrlMap.getOfdUrl());
                tSalInvoiceIssue.seteInvoiceXmlUrl(formatCreateUrlMap.getXmlUrl());
            }
            String eInvoiceUrl = response.getResponse().getEInvoiceUrl();
            String fileType = response.getResponse().getFileType();
            switch(fileType){
                case "XML":
                    tSalInvoiceIssue.seteInvoiceXmlUrl(eInvoiceUrl);
                    break;
                case "OFD":
                    tSalInvoiceIssue.seteInvoiceOfdUrl(eInvoiceUrl);
                default:
                    tSalInvoiceIssue.seteInvoicePdfUrl(eInvoiceUrl);
                    break;
            }
            log.info("新的PDF地址：", tSalInvoiceIssue.geteInvoicePdfUrl());
            log.info("新的OFD地址：", tSalInvoiceIssue.geteInvoiceOfdUrl());
            log.info("新的XML地址：", tSalInvoiceIssue.geteInvoiceXmlUrl());
            tSalInvoiceIssueService.updateTSalInvoiceIssueOnly(tSalInvoiceIssue);
        }
    }

    /**
     * 填开一个销项发票
     * @param tSalInvoice  填开对象
     * @return  TSalInvoiceResponse 完整的发票对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public TSalInvoiceResponse writeAtSalInvoiceAndIssue(TSalInvoice tSalInvoice) {
        //提交人
        SysUser user = SecurityUtils.getLoginUser().getUser();

        // step5:调用开具接口
        // step6:生成 TSalInvoiceIssue 对象
        // step7: 组装 TSalInvoiceResponse  并返回

        // step1:参数校验
        if(!tSalInvoice.getInvoiceType().equals(SalInvoiceType.ELECTRIC_SPECIAL.getCode())
            &&
            !tSalInvoice.getInvoiceType().equals(SalInvoiceType.ELECTRIC_NORMAL.getCode())
        ){
            throw new ServiceException("未知的销项发票类型");
        }
        if(StringUtils.isEmpty(tSalInvoice.getBuyerName())){
            throw new ServiceException("购买方名称不能为空");
        } else {
            // 前端所传 购买方名称 实际为购方编码
            TSalBuyer tSalBuyer = tSalBuyerService.selectTSalBuyerByNumber(tSalInvoice.getBuyerNumber());
            tSalInvoice.setBuyerName(tSalBuyer.getBuyerName());
        }
        if(StringUtils.isEmpty(tSalInvoice.getSellerName())){
            throw new ServiceException("销售方名称不能为空");
        }
        if(StringUtils.isEmpty(tSalInvoice.getSellerNumber())){
            throw new ServiceException("销售方纳税人识别号不能为空");
        }
        if(StringUtils.isEmpty(tSalInvoice.getSellerAddress())){
            throw new ServiceException("销售方地址不能为空");
        }
        if(StringUtils.isEmpty(tSalInvoice.getSellerTel())){
            throw new ServiceException("销售方电话不能为空");
        }
        if(StringUtils.isEmpty(tSalInvoice.getSellerBank())){
            throw new ServiceException("销售方开户行不能为空");
        }
        if(StringUtils.isEmpty(tSalInvoice.getSellerAccount())){
            throw new ServiceException("销售方银行账号不能为空");
        }
        if(!StringUtils.isEmpty(tSalInvoice.getCollectMobile())){
            // FIXME 接收手机格式校验
        }
        if(!StringUtils.isEmpty(tSalInvoice.getCollectMail())){
            // FIXME 接收邮箱格式校验
        }
        // step2:金额校验
        if(tSalInvoice.getFee() == null){
            throw new ServiceException("价税合计不能为空");
        }
        if(tSalInvoice.getFee().compareTo(BigDecimal.ZERO) <= 0){
            throw new ServiceException("价税合计必须大于0");
        }
        if(tSalInvoice.getTax() == null){
            throw new ServiceException("税额不能为空");
        }
        if(tSalInvoice.getTax().compareTo(BigDecimal.ZERO) <= 0){
            throw new ServiceException("税额必须大于0");
        }
        if(!StringUtils.isEmpty(tSalInvoice.getInvoiceRemark()) && tSalInvoice.getInvoiceRemark().length() >200){
            throw new ServiceException("备注不长于200个字符");
        }

        // step3:明细项校验
        if(CollectionUtils.isEmpty(tSalInvoice.getTSalInvoiceEntryList())){
            throw new ServiceException("明细行不能为空");
        }
        Set<String> productCodeSet = new HashSet<>();
        for(TSalInvoiceEntry tSalInvoiceEntry : tSalInvoice.getTSalInvoiceEntryList()){
            if(StringUtils.isEmpty(tSalInvoiceEntry.getProductCode())){
                throw new ServiceException("明细行产品不能为空");
            }
            if(tSalInvoiceEntry.getQty().compareTo(BigDecimal.ZERO) <= 0){
                throw new ServiceException("明细行产品数量必须大于0");
            }
            if(tSalInvoiceEntry.getPrice().compareTo(BigDecimal.ZERO) <= 0){
                throw new ServiceException("明细行产品单价必须大于0");
            }
            if(tSalInvoiceEntry.getAmount().compareTo(BigDecimal.ZERO) <= 0){
                throw new ServiceException("明细行产品金额必须大于0");
            }
            if(tSalInvoiceEntry.getTax().compareTo(BigDecimal.ZERO) < 0){
                throw new ServiceException("明细行产品税额不能小于0");
            }
            if(productCodeSet.contains(tSalInvoiceEntry.getProductCode())){
                throw new ServiceException("明细行项目不能重复");
            }
            productCodeSet.add(tSalInvoiceEntry.getProductCode());
        }
        // step4:生成一个 TSalInvoice 对象，需要有别于订单生成的，前缀为 RSTK
        tSalInvoice.setInvoiceId(IdUtils.simpleUUID());
        tSalInvoice.setApplyNo(IdUtils.getServiceNo("RSTK"));
        // 客户邮箱
        String collectMail = "";
        // 抄送邮箱
        String emailCarbonCopy = "";
        // 查询购买方
        TSalBuyer buyer = tSalBuyerService.selectTSalBuyerByNumber(tSalInvoice.getBuyerNumber());
        // 若前端不填写购买方邮箱，则使用购买方的第一个邮箱
        if(StringUtils.isEmpty(tSalInvoice.getCollectMail())){
            if(StringUtils.isEmpty(buyer.getEmail())){
                throw new ServiceException("必须填写客户邮箱！");
            }
            collectMail = buyer.getEmail();
        } else {
            // TODO 对前端所传邮箱做格式校验
            collectMail = tSalInvoice.getCollectMail();
        }
        if(StringUtils.isEmpty(tSalInvoice.getEmailCarbonCopy())){
            emailCarbonCopy = buyer.getEmailCarbonCopy();
        } else {
            // TODO 对前端所传邮箱做格式校验
            emailCarbonCopy = tSalInvoice.getEmailCarbonCopy();
        }
        tSalInvoice.setCollectMail(collectMail);
        tSalInvoice.setCollectMail(emailCarbonCopy);

        // 电话
        if(StringUtils.isEmpty(tSalInvoice.getBuyerTel())){
            if(StringUtils.isEmpty(buyer.getBuyerTel())){
                throw new ServiceException("必须填写客户手机号码！");
            }
            else {
                tSalInvoice.setBuyerTel(buyer.getBuyerTel());
            }
        }
        // 默认为待处理状态
        tSalInvoice.setProcessStatus(ProcessStatus.PENDING_INVOICING.getCode());
        tSalInvoice.setProcessStatusName(ProcessStatus.PENDING_INVOICING.getName());
        tSalInvoice.setCreateBy(user.getUserName());
        tSalInvoice.setCreateTime(DateUtils.getNowDate());
        // 插入
        insertTSalInvoice(tSalInvoice);
        // 开票
        issueByTSalInvoice(tSalInvoice);
        TSalInvoiceResponse response = new TSalInvoiceResponse();
        BeanUtils.copyProperties(tSalInvoice, response);
        return response;
    }

    /**
     *
     * @param ids
     */
    @Override
    public void synctSalInvoiceByIds(Long[] ids) {
        for(Long id : ids){
            TSalInvoice tSalInvoice = tSalInvoiceMapper.selectTSalInvoiceById(id);
            // 某些情况下，TSalInvoice 中无 InvoiceNo 而 对应 t_sal_invoice_issue有 InvoiceNo
            if(StringUtils.isEmpty(tSalInvoice.getInvoiceNo())){
                TSalInvoiceIssue tSalInvoiceIssue = tSalInvoiceIssueService.selectTSalInvoiceIssueByInvoiceId(tSalInvoice.getInvoiceId());
                tSalInvoice.setInvoiceNo(tSalInvoiceIssue.getInvoiceNo());
                tSalInvoice.setInvoiceType(tSalInvoiceIssue.getInvoiceTypeCode());
                tSalInvoice.setInvoiceTypeName(DictUtils.getDictLabel("invoice_type", tSalInvoiceIssue.getInvoiceTypeCode()));
                tSalInvoiceMapper.updateTSalInvoice(tSalInvoice);
            }
            // 异步调用查询接口( 即 queryAndSaveInvoiceByInvoiceNo 方法)
            ImsAsyncManager.me().execute(ImsAsyncFactory.syncInvoiceFromBaiwang(tSalInvoice.getSellerNumber(), tSalInvoice.getApplyNo(), tSalInvoice.getInvoiceNo()));
        }
    }

    /**
     *
     * @param tScSettlebill
     * @return
     */
    private TSalInvoice generateInvoiceBySettlebill(TScSettlebillRequest tScSettlebill){
        if(tScSettlebill.getInvoiceType() == null){
            throw new ServiceException("结算单" + tScSettlebill.getSettleId() + "缺失发票类型");
        }
        if(CollectionUtils.isEmpty(tScSettlebill.getTScSettlebillEntryList())){
            throw new ServiceException("结算单" + tScSettlebill.getSettleId() + "缺失明细");
        }
        //提交人
        SysUser user = SecurityUtils.getLoginUser().getUser();
        TSalInvoice tSalInvoice = new TSalInvoice();
        BeanUtils.copyProperties(tScSettlebill, tSalInvoice);
        tSalInvoice.setApplyNo(IdUtils.getServiceNo("FP"));
        tSalInvoice.setProcessStatus(ProcessStatus.PENDING_INVOICING.getCode());
        tSalInvoice.setProcessStatusName(ProcessStatus.PENDING_INVOICING.getName());
        tSalInvoice.setInvoiceRemark(tScSettlebill.getRemark());
        // 其他状态留空
        tSalInvoice.setInvoiceId(IdUtils.simpleUUID());
        tSalInvoice.setId(null);
        tSalInvoice.setCreateBy(user.getUserName());
        tSalInvoice.setCreateTime(DateUtils.getNowDate());
        tSalInvoice.setUpdateBy(null);
        tSalInvoice.setUpdateTime(null);
        return tSalInvoice;
    }

    /**
     *
     * @param tScSettlebill
     * @return
     */
    private TSalInvoice generateInvoiceByMergeSettlebill(TScSettlebillRequest tScSettlebill){
        if(tScSettlebill.getInvoiceType() == null){
            throw new ServiceException("结算单集合" + tScSettlebill.getSettleId() + "缺失发票类型");
        }
        if(CollectionUtils.isEmpty(tScSettlebill.getTScSettlebillEntryList())){
            throw new ServiceException("结算单集合" + tScSettlebill.getSettleId() + "缺失明细");
        }
        //提交人
        SysUser user = SecurityUtils.getLoginUser().getUser();
        TSalInvoice tSalInvoice = new TSalInvoice();
        BeanUtils.copyProperties(tScSettlebill, tSalInvoice);
        tSalInvoice.setApplyNo(IdUtils.getServiceNo("FPH"));
        tSalInvoice.setProcessStatus(ProcessStatus.PENDING_INVOICING.getCode());
        tSalInvoice.setProcessStatusName(ProcessStatus.PENDING_INVOICING.getName());
        // 因为是合并的待开票，所以无法在发票中保存某个具体的结算单号
        tSalInvoice.setRemark("由结算单"+tSalInvoice.getSettleId()+"合并");
        tSalInvoice.setSettleId("合并");
        tSalInvoice.setOrderNo("合并");
        tSalInvoice.setSourceOrderNo("合并");

        // 其他状态留空
        tSalInvoice.setInvoiceId(IdUtils.simpleUUID());
        tSalInvoice.setId(null);
        tSalInvoice.setCreateBy(user.getUserName());
        tSalInvoice.setCreateTime(DateUtils.getNowDate());
        tSalInvoice.setUpdateBy(null);
        tSalInvoice.setUpdateTime(null);
        return tSalInvoice;
    }
    /**
     *
     * @param tScSettlebill
     * @return
     */
    private List<TSalInvoiceEntry> generateInvoiceEntryListBySettlebill(TScSettlebillRequest tScSettlebill){
        //提交人
        SysUser user = SecurityUtils.getLoginUser().getUser();

        List<TSalInvoiceEntry> tSalInvoiceEntryList = new ArrayList<>();
        for(TScSettlebillEntryRequest tScSettlebillEntryRequest : tScSettlebill.getTScSettlebillEntryList()){
            TSalInvoiceEntry tSalInvoiceEntry = new TSalInvoiceEntry();
            BeanUtils.copyProperties(tScSettlebillEntryRequest, tSalInvoiceEntry);

            tSalInvoiceEntry.setOrderNo(tScSettlebill.getOrderNo());
            tSalInvoiceEntry.setSourceOrderNo(tScSettlebill.getSourceOrderNo());
            tSalInvoiceEntry.setSettleId(tScSettlebill.getSettleId());
            // 开票明细，需要使用pkProduct字段内容
            tSalInvoiceEntry.setProductCode(tScSettlebillEntryRequest.getProductCode());
            tSalInvoiceEntry.setProductName(tScSettlebillEntryRequest.getProductName());
            tSalInvoiceEntry.setSpecificatCode(tScSettlebillEntryRequest.getSpecificatCode());
            tSalInvoiceEntry.setUnit(tScSettlebillEntryRequest.getUnit());
            tSalInvoiceEntry.setTaxRate(tScSettlebillEntryRequest.getKpProduct().getTaxRate());
            tSalInvoiceEntry.setPrice(tScSettlebillEntryRequest.getPrice());
            // 税额
            tSalInvoiceEntry.setTax(tScSettlebillEntryRequest.getAmount().subtract(tScSettlebillEntryRequest.getWithoutAmount()));

            // FIXME 结算单明细无行号
            tSalInvoiceEntry.setSettleLineNo(tScSettlebillEntryRequest.getId());
            tSalInvoiceEntry.setId(null);
            tSalInvoiceEntry.setCreateBy(user.getUserName());
            tSalInvoiceEntry.setCreateTime(DateUtils.getNowDate());
            tSalInvoiceEntry.setUpdateBy(null);
            tSalInvoiceEntry.setUpdateTime(null);
            tSalInvoiceEntryList.add(tSalInvoiceEntry);
        }
        return tSalInvoiceEntryList;
    }

    /**
     * 将开具接口的返回转为本地对象
     * @param response
     * @return
     */
    private TSalInvoiceIssue convertToTSalInvoiceIssue(TSalInvoice tSalInvoice, OutputInvoiceIssueResponse response){
        //提交人
        SysUser user = SecurityUtils.getLoginUser().getUser();
        TSalInvoiceIssue tSalInvoiceIssue = new TSalInvoiceIssue();
        // 本地发票单ID
        tSalInvoiceIssue.setInvoiceId(tSalInvoice.getInvoiceId());
        tSalInvoiceIssue.setCustId(tSalInvoice.getCustId());
        tSalInvoiceIssue.setSiteCode(tSalInvoice.getSiteCode());
        tSalInvoiceIssue.setSiteName(tSalInvoice.getSiteName());
        tSalInvoiceIssue.setSerialNo(tSalInvoice.getApplyNo());
        if(!response.getSuccess()){
            // 返回错误中，有一种情况是超时未开出 70186 ，需要返回ResultFlag = 70186
            tSalInvoiceIssue.setResultFlag(response.getErrorResponse().getSubCode());
            return tSalInvoiceIssue;
        }
        tSalInvoiceIssue.setResultId(IdUtils.simpleUUID());
        tSalInvoiceIssue.setResultFlag("0");

        //
        List<OutputInvoiceIssueInvoiceResult> outputInvoiceIssueInvoiceResultList = response.getResponse().getSuccess();
        OutputInvoiceIssueInvoiceResult outputInvoiceIssueInvoiceResult = outputInvoiceIssueInvoiceResultList.get(0);
        // 合计金额
        tSalInvoiceIssue.setInvoiceTotalPrice(outputInvoiceIssueInvoiceResult.getInvoiceTotalPrice());
        // 合计税额
        tSalInvoiceIssue.setInvoiceTotalTax(outputInvoiceIssueInvoiceResult.getInvoiceTotalTax());
        // 价税合计
        tSalInvoiceIssue.setInvoiceTotalPriceTax(outputInvoiceIssueInvoiceResult.getInvoiceTotalPriceTax());
        // 发票代码
        tSalInvoiceIssue.setInvoiceCode(outputInvoiceIssueInvoiceResult.getInvoiceCode());
        // 	发票号码
        tSalInvoiceIssue.setInvoiceNo(outputInvoiceIssueInvoiceResult.getInvoiceNo());
        // 校验码
        tSalInvoiceIssue.setInvoiceCheckCode(outputInvoiceIssueInvoiceResult.getInvoiceCheckCode());
        // 开票日期 格式：yyyyMMddHHmmss, 转为 YYYY_MM_DD_HH_MM_SS 格式
        try {
            tSalInvoiceIssue.setInvoiceDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.parseDate(outputInvoiceIssueInvoiceResult.getInvoiceDate(),DateUtils.YYYYMMDDHHMMSS)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        // tSalInvoiceIssue.setInvoiceDate(outputInvoiceIssueInvoiceResult.getInvoiceDate());
        // 二维码 8182
        tSalInvoiceIssue.setInvoiceQrCode(outputInvoiceIssueInvoiceResult.getInvoiceQrCode());
        // 税控码，发票类型为01/02时不返回此参数
        tSalInvoiceIssue.setTaxControlCode(outputInvoiceIssueInvoiceResult.getTaxControlCode());
        // 发票类型代码
        tSalInvoiceIssue.setInvoiceTypeCode(outputInvoiceIssueInvoiceResult.getInvoiceTypeCode());
        // 电票版式文件链接。文件生成/下载存在延迟，未获取到文件流，请继续补偿获取。
        tSalInvoiceIssue.seteInvoicePdfUrl(outputInvoiceIssueInvoiceResult.getEInvoiceUrl());
        // 纸质发票代码
        tSalInvoiceIssue.setPaperInvoiceCode(outputInvoiceIssueInvoiceResult.getPaperInvoiceCode());
        // 纸质发票号码
        tSalInvoiceIssue.setPaperInvoiceNo(outputInvoiceIssueInvoiceResult.getPaperInvoiceNo());
        // 共同购买方标识
        tSalInvoiceIssue.setMulPurchaserMark(outputInvoiceIssueInvoiceResult.getMulPurchaserMark());
        tSalInvoiceIssue.setCreateTime(DateUtils.getNowDate());
        tSalInvoiceIssue.setCreateBy(user.getUserName());
        // 明细
        List<TSalInvoiceIssueEntry>  tSalInvoiceIssueEntryList = new ArrayList<>();
        List<OutputInvoiceIssuePreInvoiceDetailVO> outputInvoiceIssuePreInvoiceDetailVOList = outputInvoiceIssueInvoiceResult.getInvoiceDetailsList();
        for(OutputInvoiceIssuePreInvoiceDetailVO outputInvoiceIssuePreInvoiceDetailVO : outputInvoiceIssuePreInvoiceDetailVOList){
            TSalInvoiceIssueEntry tSalInvoiceIssueEntry = new TSalInvoiceIssueEntry();
            tSalInvoiceIssueEntry.setInvoiceId(tSalInvoice.getInvoiceId());
            tSalInvoiceIssueEntry.setEntryId(IdUtils.simpleUUID());
            tSalInvoiceIssueEntry.setCustId(tSalInvoice.getCustId());
            tSalInvoiceIssueEntry.setSiteCode(tSalInvoice.getSiteCode());
            tSalInvoiceIssueEntry.setSiteName(tSalInvoice.getSiteName());

            //
            tSalInvoiceIssueEntry.setGoodsLineNo(outputInvoiceIssuePreInvoiceDetailVO.getGoodsLineNo());
            // FIXME invoiceLineNature 缺失
            // tSalInvoiceIssueEntry.setInvoiceLineNature(outputInvoiceIssuePreInvoiceDetailVO.getinvoiceLineNature);
            //
            tSalInvoiceIssueEntry.setGoodsCode(outputInvoiceIssuePreInvoiceDetailVO.getGoodsCode());
            //
            tSalInvoiceIssueEntry.setGoodsName(outputInvoiceIssuePreInvoiceDetailVO.getGoodsName());
            //
            tSalInvoiceIssueEntry.setGoodsSpecification(outputInvoiceIssuePreInvoiceDetailVO.getGoodsSpecification());
            //
            tSalInvoiceIssueEntry.setGoodsUnit(outputInvoiceIssuePreInvoiceDetailVO.getGoodsUnit());
            //
            tSalInvoiceIssueEntry.setGoodsQuantity(outputInvoiceIssuePreInvoiceDetailVO.getGoodsQuantity());
            //
            tSalInvoiceIssueEntry.setGoodsPrice(outputInvoiceIssuePreInvoiceDetailVO.getGoodsPrice());
            //
            tSalInvoiceIssueEntry.setGoodsTotalPrice(outputInvoiceIssuePreInvoiceDetailVO.getGoodsTotalPrice());
            //
            tSalInvoiceIssueEntry.setGoodsTotalTax(outputInvoiceIssuePreInvoiceDetailVO.getGoodsTotalTax());
            //
            tSalInvoiceIssueEntry.setGoodsTaxRate(outputInvoiceIssuePreInvoiceDetailVO.getGoodsTaxRate());
            //
            tSalInvoiceIssueEntry.setPriceTaxMark(outputInvoiceIssuePreInvoiceDetailVO.getPriceTaxMark());
            // FIXME VatSpecialManagement 缺失
            // tSalInvoiceIssueEntry.setVatSpecialManagement(outputInvoiceIssuePreInvoiceDetailVO.getva);
            // FIXME FreeTaxMark 缺失
            // tSalInvoiceIssueEntry.setFreeTaxMark(outputInvoiceIssuePreInvoiceDetailVO.getfr);
            // FIXME PreferentialMark 缺失
            // tSalInvoiceIssueEntry.setPreferentialMark(outputInvoiceIssuePreInvoiceDetailVO.getPre);
            //
            // tSalInvoiceIssueEntry.setcre(outputInvoiceIssuePreInvoiceDetailVO.get);
            tSalInvoiceIssueEntry.setCreateTime(DateUtils.getNowDate());
            tSalInvoiceIssueEntry.setCreateBy(user.getUserName());
            tSalInvoiceIssueEntryList.add(tSalInvoiceIssueEntry);
        }
        tSalInvoiceIssue.setTSalInvoiceIssueEntryList(tSalInvoiceIssueEntryList);
        return tSalInvoiceIssue;
    }

    /**
     * 将开具接口的返回转为本地对象
     * @param response
     * @return
     */
    private TSalInvoiceRedConfirm convertToTSalInvoiceRedConfirm(TSalInvoice tSalInvoice, OutputRedinvoiceAddResponse response){
        //提交人
        SysUser user = SecurityUtils.getLoginUser().getUser();
        TSalInvoiceRedConfirm tSalInvoiceRedConfirm = new TSalInvoiceRedConfirm();
        if(!response.getSuccess()){
            // 返回错误
            tSalInvoiceRedConfirm.setReturnCode(response.getErrorResponse().getSubCode());
            return tSalInvoiceRedConfirm;
        }
        tSalInvoiceRedConfirm.setReturnCode("0");
        tSalInvoiceRedConfirm.setResultId(IdUtils.simpleUUID());
        tSalInvoiceRedConfirm.setRedConfirmNo(response.getResponse().get(0).getRedConfirmNo());
        tSalInvoiceRedConfirm.setRedConfirmSerialNo(response.getResponse().get(0).getRedConfirmSerialNo());
        tSalInvoiceRedConfirm.setRedinvoiceNo(response.getResponse().get(0).getRedInvoiceNo());
        tSalInvoiceRedConfirm.setConfirmBillingMark(response.getResponse().get(0).getConfirmBillingMark());
        tSalInvoiceRedConfirm.setConfirmState(response.getResponse().get(0).getConfirmState());
        tSalInvoiceRedConfirm.setCreateTime(DateUtils.getNowDate());
        tSalInvoiceRedConfirm.setCreateBy(user.getUserName());
        return tSalInvoiceRedConfirm;
    }

    /**
     * 开票
     * @param tSalInvoice
     */
    private void issueByTSalInvoice(TSalInvoice tSalInvoice){
        //提交人
        SysUser user = SecurityUtils.getLoginUser().getUser();
        // 校验处理状态
        if(!tSalInvoice.getProcessStatus().equals(ProcessStatus.PENDING_INVOICING.getCode())){
            throw new ServiceException("提示 选择的数据必须为待开票状态，请检查！");
        }
        // 百望开具接口，开票对象
        InvoiceForIssue invoiceForIssue = new InvoiceForIssue();
        BeanUtils.copyProperties(tSalInvoice, invoiceForIssue);

        // 百望开具接口，开票对象明细
        List<InvoiceEntryForIssue> invoiceEntryForIssueList = new ArrayList<>();
        // 查询t_sal_product，获取税收分类编码
        for(TSalInvoiceEntry tSalInvoiceEntry : tSalInvoice.getTSalInvoiceEntryList()){
            InvoiceEntryForIssue invoiceEntryForIssue = new InvoiceEntryForIssue();
            BeanUtils.copyProperties(tSalInvoiceEntry, invoiceEntryForIssue);
            // 查询对应的销项商品
            TSalProduct salProduct = tSalProductService.selectTSalProductByCode(tSalInvoiceEntry.getProductCode());
            if(Objects.isNull(salProduct)){
                throw new ServiceException("提示 [" + salProduct.getProductCode() + "]该商品编码不存在，请检查！");
            }
            // 税收分类编码
            invoiceEntryForIssue.setTaxCode(salProduct.getTaxCode());
            invoiceEntryForIssue.setTaxName(salProduct.getTaxName());
            invoiceEntryForIssue.setIsPolicy(salProduct.getIsPolicy());
            invoiceEntryForIssue.setFreeTaxType(salProduct.getFreeTaxType());
            invoiceEntryForIssue.setFreeTaxTypeName(salProduct.getFreeTaxTypeName());
            invoiceEntryForIssue.setRefundTaxType(salProduct.getRefundTaxType());
            invoiceEntryForIssue.setRefundTaxTypeName(salProduct.getRefundTaxTypeName());
            invoiceEntryForIssue.setPolicyCode(salProduct.getPolicyCode());
            invoiceEntryForIssue.setPolicyName(salProduct.getPolicyName());
            invoiceEntryForIssueList.add(invoiceEntryForIssue);
        }
        invoiceForIssue.setInvoiceEntryForIssueList(invoiceEntryForIssueList);
        OutputInvoiceIssueResponse response = BaiwangUtils.invoiceIssue(invoiceForIssue);
        // 保存开具接口的返回
        TSalInvoiceIssue tSalInvoiceIssue = convertToTSalInvoiceIssue(tSalInvoice, response);
        tSalInvoiceIssueService.insertTSalInvoiceIssue(tSalInvoiceIssue);
        // 更新发票单
        if(tSalInvoiceIssue.getResultFlag().equals("0")){
            // 已开票
            tSalInvoice.setProcessStatus(ProcessStatus.INVOICED.getCode());
            tSalInvoice.setProcessStatusName(ProcessStatus.INVOICED.getName());
            // 发票号码登信息更新
            tSalInvoice.setInvoiceCode(tSalInvoiceIssue.getInvoiceCode());
            tSalInvoice.setInvoiceNo(tSalInvoiceIssue.getInvoiceNo());
            tSalInvoice.setInvoiceDate(tSalInvoiceIssue.getInvoiceDate());
            if(!Objects.isNull(tSalInvoice.getTax()) && tSalInvoice.getTax().compareTo(tSalInvoiceIssue.getInvoiceTotalTax()) != 0){
                log.info("发票单{}本地税额{}与开具接口返回税额{}不一致", tSalInvoice.getApplyNo(), tSalInvoice.getTax(), tSalInvoiceIssue.getInvoiceTotalTax());
            }
            tSalInvoice.setTax(tSalInvoiceIssue.getInvoiceTotalTax());
            tSalInvoice.setFeeWithoutTax(tSalInvoiceIssue.getInvoiceTotalPrice());
            // 发票状态
            tSalInvoice.setInvoiceStatus(InvoiceStatus.NORMAL.getCode());
            tSalInvoice.setInvoiceStatusName(InvoiceStatus.NORMAL.getName());
        }
        // 发票开具超时,发送定时任务，再次调用开具接口，发票状态暂时改为 开票中
        else if(tSalInvoiceIssue.getResultFlag().equals("70186")){
            // 已开票
            tSalInvoice.setProcessStatus(ProcessStatus.INVOICING.getCode());
            tSalInvoice.setProcessStatusName(ProcessStatus.INVOICING.getName());
            // 发送再次开具任务
            redisCache.setCacheObject("task_invoice_issue", tSalInvoice.getId());
        }
        tSalInvoice.setUpdateTime(DateUtils.getNowDate());
        tSalInvoice.setUpdateBy(user.getUserName());
        tSalInvoiceMapper.updateTSalInvoice(tSalInvoice);
        // 异步调用查询接口( 即 queryAndSaveInvoiceByInvoiceNo 方法)
        ImsAsyncManager.me().execute(ImsAsyncFactory.syncInvoiceFromBaiwang(tSalInvoice.getSellerNumber(), tSalInvoice.getApplyNo(), tSalInvoice.getInvoiceNo()));

    }
}
